package lambda;

import com.google.common.collect.Lists;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Collectors
 * @author long
 */
public class LambdaCollectors {

    @Test
    public void test1() {
        List<People> list = Lists.newArrayList(
                new People(2,"201",1000d,"1",Lists.newArrayList("tom")),
                new People(1,"102",10010d,"2",Lists.newArrayList("jack","lucy")),
                new People(1,"101",20001d,"3",Lists.newArrayList("jackson","lilei")));

        // ----------------------搜集到集合----------------------
        // 搜集名称到List集合
        List<String> nameList = list.stream().map(People::getName).collect(Collectors.toList());

        // 搜集名称到Set集合 去重复
        Set<String> nameSet = list.stream().map(People::getName).collect(Collectors.toSet());

        // 搜集名称到TreeSet 有序 不重复 正序
        Set<String> treeSet = list.stream().map(People::getName).collect(Collectors.toCollection(TreeSet::new));

        // 搜集名称到TreeSet 有序 不重复 倒序
        TreeSet<String> treeSetReverse = list.stream().map(People::getName)
                .collect(Collectors.toCollection(()-> {return new TreeSet<>((o1, o2) -> o2.compareTo(o1));}));

        // ----------------------搜集到拼接----------------------
        // 直接拼接 [a,b,c] 拼接后 abc
        String joined = list.stream().map(People::getName).collect(Collectors.joining());
        System.out.println("拼接1后："+joined);

        // 转换元素后拼接 [a,b,c] 拼接后 a,b,c
        joined = list.stream().map(People::getName).collect(Collectors.joining(","));
        System.out.println("拼接2后："+joined);

        // 转换元素后拼接 [a,b,c] 拼接后 prea,b,csuf
        joined = list.stream().map(People::getName).collect(Collectors.joining(",","pre","suf"));
        System.out.println("拼接3后："+joined);

        // ----------------------汇总累积----------------------
        // 计算所有人的总工资
        double total = list.stream().collect(Collectors.summingDouble(People::getSalary));

        // 等价于下面这两个
        total = list.stream().mapToDouble(People::getSalary).sum();
        total = list.stream().map(People::getSalary).reduce(0d, Double::sum);

        // ----------------------分组----------------------
        // 按照部门分组
        Map<String, List<People>> byDeptMap = list.stream().collect(Collectors.groupingBy(People::getDepartment));

        // 计算每个部门的总工资
        Map<String, Double> totalByDeptMap = list.stream()
                .collect(Collectors.groupingBy(People::getDepartment, Collectors.summingDouble(People::getSalary)));
        System.out.println("计算每个部门的总工资1："+totalByDeptMap);

        totalByDeptMap = list.stream()
                .collect(Collectors.groupingBy(People::getDepartment, Collectors.reducing(0d,People::getSalary,Double::sum)));
        System.out.println("计算每个部门的总工资2："+totalByDeptMap);

        // 将集合分成2部分，大于等于10000 小于10000
        Map<Boolean, List<People>> greatLessMap = list.stream()
                .collect(Collectors.partitioningBy(s -> s.getSalary() >= 10000D));

        // 先对数据分组，然后根据map中的key排序
        Map<Integer,List<People>> map = list.stream()
                .collect(Collectors.groupingBy(People::getId, TreeMap::new,Collectors.toList()));

        // 先对数据分组，然后根据map中的key倒序排列
        Map<Integer,List<People>> map2 = list.stream().collect(Collectors
                .groupingBy(People::getId,()->{
                    return new TreeMap<Integer,List<People>>(new Comparator<Integer>(){
                        @Override
                        public int compare(Integer o1, Integer o2) {
                            return o2.compareTo(o1);
                        }
                    });
                },Collectors.toList()));
        System.out.println(map2);

        // 先对数据分组，然后根据map中的key倒序排列简化版
        Map<Integer,List<People>> map3 = list.stream().collect(Collectors.groupingBy(People::getId,
                ()-> new TreeMap<>(Comparator.reverseOrder()),Collectors.toList()));
        System.out.println(map3);

        // 先按照id分组，然后将每一组集合对象转换为名称再搜集起来
        Map<Integer,Set<String>> idNameListMap = list.stream().collect(Collectors.groupingBy(People::getId,
                Collectors.mapping(People::getName,Collectors.toSet())));

        // 对集合的结果进行去重排序
        List<People> sortedList = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                new TreeSet<>(Comparator.comparing(People::getId))), ArrayList::new));
        System.out.println(list);

        // 先分组 再排序
        Map<String,List<People>> sortedByDeptMap = list.stream()
                .collect(Collectors.groupingBy(People::getDepartment, Collectors.collectingAndThen(Collectors.toCollection(() ->
                        new TreeSet<>(Comparator.comparing(People::getId))), ArrayList::new)));
    }

}
